home *** CD-ROM | disk | FTP | other *** search
- #include "xinternl.h"
- #include <conio.h>
- #include <mem.h>
- /*==================================================================
- XLINE.CPP contains the code for simple bresenham lines in mode x.
- Modified from w_modex.zip code, author unknown.
-
- Modified March 1995 by Victor B. Putz.
- ===================================================================*/
-
- WORD abPlaneMask[] = {
- 0x0102,
- 0x0202,
- 0x0402,
- 0x0802
- };
-
- extern unsigned char abLeftClipPlaneMask[];
- extern unsigned char abRightClipPlaneMask[];
-
- extern BYTE * pbVGABuffer;
- extern int ScrnLogicalByteWidth;
-
-
-
- void _HorizontalLine(
- xPageHandle_t wOffset,
- xScreenCoord_t iLeftX,
- xScreenCoord_t iY,
- int iLength,
- xColor_t iColor
- )
- {
- if ( iLength < 0 ) {
- return;
- }
- BYTE * pb = pbVGABuffer + wOffset + ( ScrnLogicalByteWidth * iY ) + iLeftX / 4;
- int iTemp;
- //do the left part of the line
- if ( iTemp = ( iLeftX & 3 ) ) {
- outp( SC_INDEX, 0x02 );
- outp( SC_INDEX + 1, abLeftClipPlaneMask[ iTemp ] );
- *pb++ = ( BYTE )iColor;
- iLength -= ( 4 - iTemp );
- }
- if ( iLength < 0 ) {
- return;
- }
- //the middle
- if ( iTemp = ( iLength >> 2 ) ) {
- outpw( SC_INDEX, 0x0f02 );
- iLength &= 3;
- memset( pb, iColor, iTemp );
- pb += iTemp;
- }
- //then the right part
- if ( iLength ) {
- outp( SC_INDEX, 0x02 );
- outp( SC_INDEX + 1, abRightClipPlaneMask[ iLength ] );
- *pb = ( BYTE )iColor;
- }
- }
-
-
- void _VerticalLine(
- xPageHandle_t wOffset,
- xScreenCoord_t iX,
- xScreenCoord_t iTopY,
- int iLength,
- xColor_t iColor
- )
- {
- int iTemp = ( iX & 3 );
-
- outpw(SC_INDEX, abPlaneMask[iTemp]);
-
- BYTE * pbDest = pbVGABuffer + wOffset + ( iTopY * ScrnLogicalByteWidth ) + (iX / 4);
-
- while (iLength--) {
- *pbDest = ( BYTE )iColor;
- pbDest += ScrnLogicalByteWidth;
- }
- }
-
-
- void internal_xmajor(
- BYTE * pbDest,
- int iLength, //was short
- int iYSkip, //was short
- unsigned long ErrorAcc,
- unsigned long ErrorAdj,
- BYTE bColor
- )
- {
- if (iLength) {
- iLength--;
- while (iLength--) {
- *pbDest++ = bColor;
- ErrorAcc += ErrorAdj;
-
- if (ErrorAcc & ~0xFFFFL) {
- ErrorAcc &= 0xFFFFL;
- pbDest += iYSkip;
- }
- }
- *pbDest = bColor;
- }
- }
-
- void internal_middle(
- BYTE *pbDest,
- int iLength, //was short
- int iYSkip, //was short
- unsigned long ErrorAcc,
- unsigned long ErrorAdj,
- BYTE bColor
- )
- {
- if (iLength) {
- iLength--;
- while (iLength--) {
- *pbDest++ = bColor;
- ErrorAcc += ErrorAdj;
- pbDest += (iYSkip * (ErrorAcc >> 16));
- ErrorAcc &= 0xFFFFL;
- }
- *pbDest = bColor;
- }
- }
-
-
- void internal_ymajor(
- BYTE *pbDest,
- int iLength, //was short
- int iYSkip, //was short
- unsigned long ErrorAcc,
- unsigned long ErrorAdj,
- BYTE bColor
- )
- {
- unsigned long TinyAdj;
- int i;//was short
-
- if (iLength) {
- TinyAdj = (ErrorAdj >> 2);
- ErrorAdj -= TinyAdj;
-
- iLength--;
- while (iLength--) {
- ErrorAcc += TinyAdj;
- i = (ErrorAcc >> 16);
- ErrorAcc &= 0xFFFFL;
-
- while (i--) {
- *pbDest = bColor;
- pbDest += iYSkip;
- }
-
- ErrorAcc += ErrorAdj;
- pbDest += (iYSkip * (ErrorAcc >> 16)) + 1;
- ErrorAcc &= 0xFFFFL;
- }
- ErrorAcc += TinyAdj;
- i = (ErrorAcc >> 16);
- while (i--) {
- *pbDest = bColor;
- pbDest += iYSkip;
- }
- }
- }
-
-
-
- void x_line( /* Draw a line, what else */
- xScreenCoord_t x1,
- xScreenCoord_t y1,
- xScreenCoord_t x2,
- xScreenCoord_t y2,
- xColor_t color,
- xPageHandle_t PageBase
- )
- {
-
- unsigned long ErrorAcc, ErrorAdj, TinyAdj;
- int i, DeltaX, DeltaY, yskip; //was short
- int len[4]; //was short
- BYTE * pbDest;
- int iTemp;
-
- // Mode X 4-way folded Bresenham line function - by David Boeren
- //modified to fit XLIB by Victor Putz
-
- // Make sure the line runs left to right by swapping ends if necessary
- if (x1 > x2) {
- iTemp = x1; x1 = x2; x2 = iTemp;
- iTemp = y1; y1 = y2; y2 = iTemp;
- }
-
- DeltaX = (x2 - x1);
- DeltaY = (y2 - y1);
-
- if (DeltaY >= 0) {
- yskip = ScrnLogicalByteWidth;
- } else {
- DeltaY = -DeltaY; // Make DeltaY positive
- yskip = -ScrnLogicalByteWidth;
- }
-
- if (DeltaX == 0) {
- // Vertical Line (and one pixel lines)
- if (yskip > 0) {
- _VerticalLine(PageBase, x1, y1, (DeltaY + 1), color);
- } else {
- _VerticalLine(PageBase, x1, y2, (DeltaY + 1), color);
- }
- return;
- }
-
- if (DeltaY == 0) {
- // Horizontal Line
- _HorizontalLine(PageBase, x1, y1, (DeltaX + 1), color);
- return;
- }
-
- pbDest = pbVGABuffer + PageBase + ( y1 * ScrnLogicalByteWidth ) + (x1 / 4);
- ErrorAcc = 0x8000;
-
- // Length of sub-line in each plane
- iTemp = (x1 & 3);
- i = DeltaX + iTemp;
- len[0] = ((i--) >> 2);
- len[1] = ((i--) >> 2);
- len[2] = ((i--) >> 2);
- len[3] = (i >> 2) + 1;
-
- for (i=iTemp; i < 3; i++) {
- len[i]++;
- }
-
- if ((DeltaX >> 2) >= DeltaY) {
- // X-Major line (0.00 < slope <= 0.25)
- ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));
- TinyAdj = (ErrorAdj >> 2);
- while (i--) {
- outpw(SC_INDEX, abPlaneMask[iTemp]);
- internal_xmajor(pbDest, len[iTemp++], yskip, ErrorAcc, ErrorAdj, color);
- if (iTemp == 4) {
- iTemp = 0;
- pbDest++;
- }
- ErrorAcc += TinyAdj;
- if (ErrorAcc & ~0xFFFFL) {
- ErrorAcc &= 0xFFFFL;
- pbDest += yskip;
- }
- }
- outpw(SC_INDEX, abPlaneMask[iTemp]);
- internal_xmajor(pbDest, len[iTemp], yskip, ErrorAcc, ErrorAdj, color);
- } else if (DeltaX >= DeltaY) {
- // Middle line (0.25 < slope <= 1.00)
- ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));
- TinyAdj = (ErrorAdj >> 2);
- while (i--) {
- outpw(SC_INDEX, abPlaneMask[iTemp]);
- internal_middle(pbDest, len[iTemp++], yskip, ErrorAcc, ErrorAdj, color);
- if (iTemp == 4) {
- iTemp = 0;
- pbDest++;
- }
- ErrorAcc += TinyAdj;
- if (ErrorAcc & ~0xFFFFL) {
- pbDest += yskip;
- ErrorAcc &= 0xFFFFL;
- }
- }
- outpw(SC_INDEX, abPlaneMask[iTemp]);
- internal_middle(pbDest, len[iTemp], yskip, ErrorAcc, ErrorAdj, color);
- } else {
- // Y-Major line (slope > 1)
- ErrorAdj = ((((unsigned long)(DeltaY+1) << 18) /
- (unsigned long)(DeltaX+1)));
- TinyAdj = (ErrorAdj >> 2);
- while (i--) {
- outpw(SC_INDEX, abPlaneMask[iTemp]);
- internal_ymajor(pbDest, len[iTemp++], yskip, ErrorAcc, ErrorAdj, color);
- if (iTemp == 4) {
- iTemp = 0;
- pbDest++;
- }
- ErrorAcc += TinyAdj;
- pbDest += (yskip * (ErrorAcc >> 16));
- ErrorAcc &= 0xFFFFL;
- }
- outpw(SC_INDEX, abPlaneMask[iTemp]);
- internal_ymajor(pbDest, len[iTemp], yskip, ErrorAcc, ErrorAdj, color);
- }
- }
-